package com.example.test_app.view;

import android.content.Context;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.jetbrains.annotations.NotNull;

import java.util.List;

public class MyLayoutManager extends RecyclerView.LayoutManager {


    public MyLayoutManager(Context context) {
    }

    @Override
    public void layoutDecorated(@NonNull @NotNull View child, int left, int top, int right, int bottom) {
        super.layoutDecorated(child, left, top, right, bottom);

    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        Log.d("MyLayoutManager", "onLayoutChildren: ");

        if (state.getItemCount() == 0) {
            //没有Item可布局，就回收全部临时缓存 (参考自带的LinearLayoutManager)
            //这里的没有Item，是指Adapter里面的数据集，
            //可能临时被清空了，但不确定何时还会继续添加回来
            removeAndRecycleAllViews(recycler);
            return;
        }
        //暂时分离和回收全部有效的Item

        fill(recycler, state, 0);
    }

    private int firstPosition;
    private int firstPositionOffsetY;
    private int mOffsetY;

    private int lastStart;
    private int lastEnd;
    private boolean canScrollDown = true;


    private int fill(RecyclerView.Recycler recycler, RecyclerView.State state, int dy) {

        detachAndScrapAttachedViews(recycler);
        int i=onLayout(recycler, state, dy);
        recycleChildren(recycler);
        return i;
    }

    private void recycleChildren(RecyclerView.Recycler recycler) {
        List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
        for (int i = 0; i < scrapList.size(); i++) {
            RecyclerView.ViewHolder holder = scrapList.get(i);
            removeAndRecycleView(holder.itemView, recycler);
        }
    }


    private int onLayout(RecyclerView.Recycler recycler, RecyclerView.State state, int dy) {
        mOffsetY -= dy;
        firstPositionOffsetY -= dy;
        View item;
        int i = firstPosition;
        int height = firstPositionOffsetY;
        Log.d("MyLayoutManager", "onLayout: " + mOffsetY);
        int y = dy;
        int bottomHeight = 0;

        while (i < state.getItemCount() && height < getHeight()) {
            item = recycler.getViewForPosition(i);
            //添加进去，当然里面不一定每次都是调用RecyclerView的addView方法的，
            //如果是从缓存区里面找到的，只需调用attachView方法把它重新连接上就行了。

            addView(item,i);
            //测量item，当然，也不是每次都会调用measure方法进行测量的，
            //它里面会判断，如果已经测量过，而且当前尺寸又没有收到更新的通知，就不会重新测量。
            measureChild(item, 0, 0);

            if (i % 3 == 0) {
                //进行布局
                layoutDecoratedWithMargins(item, 0, height, 0 + getDecoratedMeasuredWidth(item), height + getDecoratedMeasuredHeight(item));
                height += getDecoratedMeasuredHeight(item);
                bottomHeight = height;
            } else {

                if (i % 3 == 2) {
                    int w = getWidth() / 2;
                    layoutDecoratedWithMargins(item, w, height, w + getDecoratedMeasuredWidth(item), height + getDecoratedMeasuredHeight(item));
                    height += getDecoratedMeasuredHeight(item);
                    bottomHeight = height;
                } else {
                    layoutDecoratedWithMargins(item, 0, height, 0 + getDecoratedMeasuredWidth(item), height + getDecoratedMeasuredHeight(item));
                    bottomHeight = height + getDecoratedMeasuredHeight(item);
                }
            }
            if (bottomHeight < 0) {
                firstPosition++;
                firstPositionOffsetY = bottomHeight;
            }
            i++;
        }

        while (firstPositionOffsetY>0&&firstPosition>0){
            firstPosition--;
            item = recycler.getViewForPosition(firstPosition);
            addView(item,firstPosition);
            measureChild(item, 0, 0);
            if (firstPosition % 3 == 0) {
                //进行布局
                layoutDecoratedWithMargins(item, 0, firstPositionOffsetY-getDecoratedMeasuredHeight(item), 0 + getDecoratedMeasuredWidth(item), firstPositionOffsetY );
                firstPositionOffsetY -= getDecoratedMeasuredHeight(item);

            } else {

                if (firstPosition % 3 == 2) {
                    int w = getWidth() / 2;
                    layoutDecoratedWithMargins(item, w, firstPositionOffsetY-getDecoratedMeasuredHeight(item), w + getDecoratedMeasuredWidth(item), firstPositionOffsetY);
                } else {
                    layoutDecoratedWithMargins(item, 0, firstPositionOffsetY-getDecoratedMeasuredHeight(item), 0 + getDecoratedMeasuredWidth(item), firstPositionOffsetY);
                    firstPositionOffsetY -= getDecoratedMeasuredHeight(item);
                }
            }
        }
        if (firstPositionOffsetY>0&&firstPosition==0){
            firstPositionOffsetY=0;
            mOffsetY=0;
        }

        if (bottomHeight < getHeight() && i >= state.getItemCount()) {
            firstPositionOffsetY = firstPositionOffsetY - bottomHeight + getHeight();
            canScrollDown = false;
            fill(recycler, state, 0);
            y = dy - getHeight() + bottomHeight;
        } else {
            canScrollDown = true;
        }


        lastEnd = i;
        lastStart = firstPosition;

        return y;
    }


    public int getDecoratedMeasurementHorizontal(View view) {
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                view.getLayoutParams();
        return getDecoratedMeasuredWidth(view) + params.leftMargin
                + params.rightMargin;
    }

    /**
     * 获取某个childView在竖直方向所占的空间
     *
     * @param view
     * @return
     */
    public int getDecoratedMeasurementVertical(View view) {
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
                view.getLayoutParams();
        return getDecoratedMeasuredHeight(view) + params.topMargin
                + params.bottomMargin;
    }

    public int getVerticalSpace() {
        return getHeight() - getPaddingTop() - getPaddingBottom();
    }

    public int getHorizontalSpace() {
        return getWidth() - getPaddingLeft() - getPaddingRight();
    }


    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        Log.d("MyLayoutManager", "scrollVerticallyBy: ");


        if (firstPosition == 0 && mOffsetY >= 0 && dy < 0) {
            mOffsetY = 0;
            fill(recycler, state, 0);
            return 0;
        }
        if (!canScrollDown && dy > 0) {
            fill(recycler, state, 0);
            return 0;
        }

        return fill(recycler, state, dy);

    }

    @Override
    public boolean canScrollVertically() {
        return true;
    }


    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {

        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT);
    }


}
